package Music_Playing;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.FloatControl;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import org.eclipse.swt.widgets.Display;

import Download.FindMusic;
import each_class.SongClass;
import javazoom.spi.mpeg.sampled.file.MpegAudioFileReader;
import ui.PlayProgressBar;
import ui.TimeView;
import ui.VolumeBar;
import ui.global.Operation;

public class Music_Playing {
	private static AudioInputStream audioInputStream;// 音频输入流
	private static AudioFormat format;// 音频流格式
	private static boolean playStartStatus = true; // 启动状态
	private static Thread thread = null; // 播放线程
	private static Clip clip; // 剪辑音频
	private static long musicAllTime; // 歌曲时长
	private static long musicCurrentTime = 0; // 当前播放时间
	private static TimeView time; // 时间标签类
	private static PlayProgressBar playProgressBar; // 进度条

	public static boolean isPlay = true;
	private static VolumeBar scaleVolume; // 音量
	private static FloatControl gainControl; // 控制音量
	public static float volume = 0;

	public static void load() {
		playProgressBar = Operation.getPlayProgressBar();
		time = Operation.getTimeView();
		scaleVolume = Operation.getVolumeBar();
	}

	// 读取音频
	public static void readMusic(InputStream in, SongClass songClass) {

		try {

			MpegAudioFileReader mp = new MpegAudioFileReader();

			audioInputStream = mp.getAudioInputStream(in);
			format = audioInputStream.getFormat();
			AudioFormat targetFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, format.getSampleRate(), 16,
					format.getChannels(), format.getChannels() * 2, format.getSampleRate(), false);
			audioInputStream = AudioSystem.getAudioInputStream(targetFormat, audioInputStream);
			clip = AudioSystem.getClip();
			clip.open(audioInputStream);

		} catch (UnsupportedAudioFileException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (LineUnavailableException e) {
			e.printStackTrace();
		}
	}

	// 播放音乐
	public static void start(SongClass songClass) throws Exception {
		load();

		try {
			closeMusic();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		musicAllTime = Long.parseLong(songClass.getSong_time());
		Display.getDefault().asyncExec(new Runnable() {
			@Override
			public void run() {
				playProgressBar.progress = 0;
				time.setProgress(0);
				time.initail(musicAllTime + "");
				playProgressBar.redraw();
			}
		});

		// System.out.println(songClass);
		InputStream in = FindMusic.findMusic(songClass);
		// System.out.println(System.currentTimeMillis());
		// System.out.println(songClass);
		System.out.println(in.available());
		if (in == null || in.available() == 0) {
			return;
		}

		Map<String, String> lyr = FindMusic.findlyric(songClass);
		// System.out.println(lyr);
		isPlay = true;
		readMusic(in, songClass);

		clip.start();
		// System.out.println(clip == null);
		gainControl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
		gainControl.setValue(volume);
		// System.out.println(scaleVolume == null);
		// scaleVolume.progress = ((double) 100);

		// System.out.println(System.currentTimeMillis());
		thread = new Thread() {
			@Override
			public void run() {

				playStartStatus = true;
				// 此处代码块上锁，保证了进度条和时间只能被当前线程修改
				synchronized (thread) {
					while (playStartStatus) {

						musicCurrentTime = clip.getMicrosecondPosition() / 1000;
						// 进度条
						Display.getDefault().asyncExec(new Runnable() { // 在SWT开一个线程
							@Override
							public void run() {

								// System.out.println(musicCurrentTime);
								playProgressBar.progress = ((double) musicCurrentTime / musicAllTime);

								// System.out.println(lyric.gainLyric(musicCurrentTime, lyr));
								Operation.setLrc(lyric.gainLyric(musicCurrentTime, lyr));

								time.setProgress(playProgressBar.progress);

								playProgressBar.redraw();
							}
						});

						if (musicCurrentTime == musicAllTime) {
							break;
						}

						try {
							sleep(100);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
					// 说明这首歌曲已经播完了
					Display.getDefault().asyncExec(new Runnable() {
						@Override
						public void run() {
							playProgressBar.progress = (double) 1;
							time.setProgress(playProgressBar.progress);
							playProgressBar.redraw();
						}
					});
				}

			}
		};

		thread.start();

	}

	/**
	 * 快进
	 * 
	 * @param progress        进度条百分比
	 * @param playProgressBar 进度条
	 */
	public static void fastForward(double progress) {

		if (clip == null) {
			return;
		}
		// System.out.println(musicAllTime + " " + progress);
		long ratio = (long) (musicAllTime * 1000 * progress); // 快进到多少微妙
		clip.setMicrosecondPosition(ratio);
		time.setProgress(musicCurrentTime);
		playProgressBar.progress = ((double) musicCurrentTime / musicAllTime);
		// playProgressBar.redraw();
	}

//暂停
	public static void pause() {

		clip.stop();
		isPlay = false;
		new Thread(new Runnable() {
			@Override
			public void run() {
				synchronized (thread) {
					try {
						thread.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					} catch (NullPointerException e) {
					}
				}
			}
		}).start();
	}

	// 继续播放
	public static void continuePlay() {
		clip.start();
		isPlay = true;
		new Thread(new Runnable() {
			@Override
			public void run() {
				// 保证线程同步
				synchronized (thread) {
					thread.notify();
				}
			}
		}).start();
	}

	// 停止

	public static void closeMusic() throws IOException {
		if (clip == null) {
			return;
		}
		if (thread != null) {
			thread.stop();
			thread = null;
		}
		audioInputStream.close();
		clip.close();
		clip = null;
		playStartStatus = false;
	}

	// 静音
	public static void openMute() {
		volume = gainControl.getValue();
		// System.out.println(volume);
		gainControl.setValue(gainControl.getMinimum());
	}

	// 关闭静音
	public static void openVoice() {

		gainControl.setValue(volume);
	}

	// 设置音量
	public static void setVolume(double selection) {

		volume = (float) ((double) 0.6 * selection * 100 - 60); // 不能超过6.
		gainControl.setValue(volume);
	}

}
